package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.DbIdentityManagementMapper;
import com.ruoyi.system.mapper.DbQualificationManagementMapper;
import com.ruoyi.system.mapper.QualificationManagementMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.IdentityManagementMapper;
import com.ruoyi.system.service.IIdentityManagementService;
import com.ruoyi.system.service.IDbIdentityManagementService;
import com.ruoyi.system.service.IScoreManagementService;
import com.ruoyi.system.service.IPhysicalManagementService;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.Validator;
import java.util.stream.Collectors;

import com.ruoyi.system.domain.dto.StatisticsDTO;
import com.ruoyi.system.domain.dto.StatisticsDTO.PositionData;

/**
 * 四级联考身份验证Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-04-02
 */
@Service
public class IdentityManagementServiceImpl implements IIdentityManagementService 
{
    private static final Logger log = LoggerFactory.getLogger(IdentityManagementServiceImpl.class);

    @Autowired
    private IdentityManagementMapper identityManagementMapper;
    
    @Autowired
    protected Validator validator;
    
    @Autowired
    private IDbIdentityManagementService dbIdentityManagementService;
    
    @Autowired
    private IScoreManagementService scoreManagementService;
    
    @Autowired
    private IPhysicalManagementService physicalManagementService;

    @Autowired
    private QualificationManagementMapper qualificationManagementMapper;

    @Autowired
    private DbIdentityManagementMapper dbIdentityManagementMapper;


    @Autowired
    private DbQualificationManagementMapper dbQualificationManagementMapper;


    @Override
    @Transactional
    public int insertIdentityListFromScore(List<ScoreManagement> scores, String operName) {
        List<IdentityManagement> identities = scores.stream()
                .map(this::convertToIdentity)
                .collect(Collectors.toList());

        if (identities.isEmpty()) {
            return 0;
        }
        identities.forEach(identity -> {
            int i = identityManagementMapper.insertIdentityManagement(identity);
        });
        return identities.size();
    }

    private IdentityManagement convertToIdentity(ScoreManagement score) {
        IdentityManagement identity = new IdentityManagement();
        // 基本信息
        identity.setCandidateId(score.getCandidateId());
        identity.setName(score.getName());
        identity.setGender(score.getGender());
        identity.setIdCard(score.getIdCard());
        identity.setExamNumber(score.getExamNumber());
        identity.setAdministrativeAptitudeScore(score.getAdministrativeAptitudeScore());
        identity.setEssayScore(score.getEssayScore());
        identity.setProfessionalSubjectScore(score.getProfessionalSubjectScore());
        identity.setTotalScore(score.getTotalScore());
        identity.setProfessionalSkillTestScore(score.getProfessionalSkillTestScore());
        identity.setAppliedUnit(score.getAppliedUnit());
        identity.setAppliedPosition(score.getAppliedPosition());
        identity.setRecruitmentNumber(score.getRecruitmentNumber());
        identity.setInterviewRatio(score.getInterviewRatio());
        identity.setRanking(score.getRanking());
        identity.setGraduationSchool(score.getGraduationSchool());
        identity.setHasProfessionalSkillTest(score.getHasProfessionalSkillTest());
        identity.setPositionCategory(score.getPositionCategory());
        identity.setIsAlternate(score.getIsAlternate());

        return identity;
    }


    /**
     * 查询四级联考身份验证
     * 
     * @param id 四级联考身份验证主键
     * @return 四级联考身份验证
     */
    @Override
    public IdentityManagement selectIdentityManagementById(Long id)
    {
        return identityManagementMapper.selectIdentityManagementById(id);
    }

    /**
     * 查询四级联考身份验证列表
     * 
     * @param identityManagement 四级联考身份验证
     * @return 四级联考身份验证
     */
    @Override
    public List<IdentityManagement> selectIdentityManagementList(IdentityManagement identityManagement)
    {
        return identityManagementMapper.selectIdentityManagementList(identityManagement);
    }

    /**
     * 新增四级联考身份验证
     * 
     * @param identityManagement 四级联考身份验证
     * @return 结果
     */
    @Override
    public int insertIdentityManagement(IdentityManagement identityManagement)
    {
        return identityManagementMapper.insertIdentityManagement(identityManagement);
    }

    /**
     * 修改四级联考身份验证
     * 
     * @param identityManagement 四级联考身份验证
     * @return 结果
     */
    @Override
    @Transactional
    public int updateIdentityManagement(IdentityManagement identityManagement)
    {
        // 先获取原记录，用于判断身份验证结果是否变更为"通过"
        IdentityManagement original = identityManagementMapper.selectIdentityManagementById(identityManagement.getId());
        
        // 执行更新操作
        int rows = identityManagementMapper.updateIdentityManagement(identityManagement);
        
        if (rows > 0 && original != null)
        {
            try
            {
                // 判断是否是从非"通过"状态变更为"通过"状态
                if (!"通过".equals(original.getIdentityVerificationResult()) && 
                    "通过".equals(identityManagement.getIdentityVerificationResult()))
                {
                    // 创建单条记录的列表，用于调用体能测评模块的插入方法
                    List<IdentityManagement> identityList = new java.util.ArrayList<>();
                    
                    // 需要使用更新后的完整记录，因此重新查询
                    IdentityManagement updatedIdentity = identityManagementMapper.selectIdentityManagementById(identityManagement.getId());
                    identityList.add(updatedIdentity);
                    
                    // 调用体能测评服务，将身份验证通过的考生流转到体能测评环节
                    int count = physicalManagementService.insertPhysicalListFromIdentity(identityList, "admin");
                    
                    if (count > 0)
                    {
                        log.info("考生[" + updatedIdentity.getName() + ", 准考证号:" + updatedIdentity.getExamNumber() 
                            + "]身份验证修改为通过，已自动流转到体能测评环节");
                    }
                }
            }
            catch (Exception e)
            {
                log.error("身份验证通过后流转到体能测评环节失败", e);
                // 不影响主流程，异常不向上抛出
            }
        }
        
        return rows;
    }

    /**
     * 批量删除四级联考身份验证
     * 
     * @param ids 需要删除的四级联考身份验证主键
     * @return 结果
     */
    @Override
    public int deleteIdentityManagementByIds(Long[] ids)
    {
        return identityManagementMapper.deleteIdentityManagementByIds(ids);
    }

    /**
     * 删除四级联考身份验证信息
     * 
     * @param id 四级联考身份验证主键
     * @return 结果
     */
    @Override
    public int deleteIdentityManagementById(Long id)
    {
        return identityManagementMapper.deleteIdentityManagementById(id);
    }

    /**
     * 导入四级联考身份验证数据
     * 
     * @param identityList 身份验证数据列表
     * @param updateSupport 是否更新支持，如果已存在，是否覆盖
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    @Transactional
    public String importIdentityData(List<IdentityManagement> identityList, boolean updateSupport, String operName)
    {
        if (StringUtils.isNull(identityList) || identityList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        
        for (IdentityManagement identity : identityList)
        {
            try
            {
                // 验证是否存在相同的准考证号或身份证号
                IdentityManagement existIdentity = new IdentityManagement();
                if (StringUtils.isNotEmpty(identity.getExamNumber()))
                {
                    existIdentity.setExamNumber(identity.getExamNumber());
                }
                else if (StringUtils.isNotEmpty(identity.getIdCard()))
                {
                    existIdentity.setIdCard(identity.getIdCard());
                }
                else
                {
                    throw new ServiceException("导入数据中准考证号和身份证号不能同时为空");
                }
                
                List<IdentityManagement> existList = identityManagementMapper.selectIdentityManagementList(existIdentity);
                
                if (StringUtils.isNull(existList) || existList.size() == 0)
                {
                    // 如果不存在，执行插入操作
                    identityManagementMapper.insertIdentityManagement(identity);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、准考证号 " + identity.getExamNumber() + " 导入成功");
                }
                else if (updateSupport)
                {
                    // 如果存在且允许更新
                    identity.setId(existList.get(0).getId()); // 设置ID，确保更新正确的记录
                    identityManagementMapper.updateIdentityManagement(identity);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、准考证号 " + identity.getExamNumber() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、准考证号 " + identity.getExamNumber() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、准考证号 " + identity.getExamNumber() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 从资格审查名单生成并插入身份验证名单
     * 
     * @param qualificationList 符合条件的资格审查名单数据列表
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    @Transactional
    public int insertIdentityListFromQualification(List<QualificationManagement> qualificationList, String operName)
    {
        if (StringUtils.isNull(qualificationList) || qualificationList.size() == 0)
        {
            throw new ServiceException("符合条件的考生数据不能为空！");
        }
        
        int successNum = 0;
        
        // 先清空现有身份验证名单数据
        IdentityManagement clearCriteria = new IdentityManagement();
        List<IdentityManagement> existingList = identityManagementMapper.selectIdentityManagementList(clearCriteria);
        if (existingList != null && existingList.size() > 0)
        {
            Long[] ids = new Long[existingList.size()];
            for (int i = 0; i < existingList.size(); i++)
            {
                ids[i] = existingList.get(i).getId();
            }
            identityManagementMapper.deleteIdentityManagementByIds(ids);
        }
        
        // 遍历符合条件的考生，插入身份验证名单
        for (QualificationManagement qualification : qualificationList)
        {
            try
            {
                // 只有资格审查结果为"通过"的考生才能进入身份验证环节
                if ("通过".equals(qualification.getQualificationReviewResult()))
                {
                    // 创建身份验证名单对象
                    IdentityManagement identity = new IdentityManagement();
                    
                    // 复制考生信息
                    identity.setCandidateId(qualification.getCandidateId());
                    identity.setName(qualification.getName());
                    identity.setGender(qualification.getGender());
                    identity.setIdCard(qualification.getIdCard());
                    identity.setExamNumber(qualification.getExamNumber());
                    identity.setAdministrativeAptitudeScore(qualification.getAdministrativeAptitudeScore());
                    identity.setEssayScore(qualification.getEssayScore());
                    identity.setProfessionalSubjectScore(qualification.getProfessionalSubjectScore());
                    identity.setTotalScore(qualification.getTotalScore());
                    identity.setProfessionalSkillTestScore(qualification.getProfessionalSkillTestScore());
                    identity.setAppliedUnit(qualification.getAppliedUnit());
                    identity.setAppliedPosition(qualification.getAppliedPosition());
                    identity.setRecruitmentNumber(qualification.getRecruitmentNumber());
                    identity.setInterviewRatio(qualification.getInterviewRatio());
                    identity.setRanking(qualification.getRanking());
                    identity.setGraduationSchool(qualification.getGraduationSchool());
                    identity.setHasProfessionalSkillTest(qualification.getHasProfessionalSkillTest());
                    identity.setPositionCategory(qualification.getPositionCategory());
                    identity.setIsAlternate(qualification.getIsAlternate());
                    identity.setQualificationReviewResult(qualification.getQualificationReviewResult());
//                    identity.setIdentityVerificationResult("待验证");  // 默认为待验证
//                    identity.setPhysicalTestResult(qualification.getPhysicalTestResult());
//                    identity.setFinalResult("待确认");  // 默认为待确认
                    
                    // 执行插入操作
                    identityManagementMapper.insertIdentityManagement(identity);
                    successNum++;
                }
            }
            catch (Exception e)
            {
                log.error("插入身份验证名单失败，准考证号：" + qualification.getExamNumber(), e);
            }
        }
        
        return successNum;
    }

    /**
     * 生成递补身份验证名单
     * 根据资格审查和身份验证结果筛选考生，并处理同分情况
     *
     * @param operName 操作用户
     * @return 递补身份验证人数
     */
    @Override
    @Transactional
    public int generateDbIdentityList(String operName) {

        // 递补身份验证表
//        dbIdentityManagementMapper.deleteAllIdentityManagement();

        // 1. 统计各职位未通过人数
        Map<String, Integer> positionFailureCount = new HashMap<>();


        // 获取资格审查不通过的考生职位
        QualificationManagement failedQualification = new QualificationManagement();
        failedQualification.setQualificationReviewResult("未通过");
        List<QualificationManagement> failedQualificationList = qualificationManagementMapper.selectQualificationManagementList(failedQualification);


        // 获取身份验证未通过的考生
        IdentityManagement failedIdentity = new IdentityManagement();
        failedIdentity.setIdentityVerificationResult("未通过");
        List<IdentityManagement> failedList = identityManagementMapper.selectIdentityManagementList(failedIdentity);

        IdentityManagement failedIdentityall = new IdentityManagement();
        List<IdentityManagement> failedListall = identityManagementMapper.selectIdentityManagementList(failedIdentityall);



        // 统计每个职位的未通过数量
        failedList.forEach(item -> {
            String positionKey = item.getAppliedUnit() + "_" + item.getAppliedPosition();
            positionFailureCount.put(positionKey, positionFailureCount.getOrDefault(positionKey, 0) + 1);
        });

        if (positionFailureCount.isEmpty()) {
            log.info("没有身份验证未通过的职位，无需递补");
            return 0;
        }

        // 2. 获取所有成绩合格考生
        List<ScoreManagement> allScores = scoreManagementService.selectScoreManagementList(new ScoreManagement());

        // 3. 构建排除条件集合
        Set<String> excludeQualificationfiers = failedQualificationList.stream()
                .map(i -> i.getExamNumber() + "_" + i.getIdCard())
                .collect(Collectors.toSet());
        Set<String> excludeIdentifiers = failedList.stream()
                .map(i -> i.getExamNumber() + "_" + i.getIdCard())
                .collect(Collectors.toSet());

        Set<String> excludeIdentifiersall = failedListall.stream()
                .map(i -> i.getExamNumber() + "_" + i.getIdCard())
                .collect(Collectors.toSet());
        excludeIdentifiersall.addAll(excludeQualificationfiers);

        // 4. 过滤有效考生（排除未通过考生）
        List<ScoreManagement> validScores = allScores.stream()
                .filter(score -> !excludeIdentifiersall.contains(score.getExamNumber() + "_" + score.getIdCard()))
                .collect(Collectors.toList());

        // 5. 按职位分组处理
        Map<String, List<ScoreManagement>> grouped = validScores.stream()
                .collect(Collectors.groupingBy(s -> s.getAppliedUnit() + "_" + s.getAppliedPosition()));

        List<ScoreManagement> finalCandidates = new ArrayList<>();

        for (Map.Entry<String, List<ScoreManagement>> entry : grouped.entrySet()) {
            String positionKey = entry.getKey();
            List<ScoreManagement> group = entry.getValue();

            // 只处理存在未通过考生的职位
            if (!positionFailureCount.containsKey(positionKey) || group.isEmpty()) continue;

            // 获取该职位需要递补的数量
            int required = positionFailureCount.get(positionKey);

            // 排序逻辑（降序）
            group.sort((a, b) -> {
                boolean hasSkillTest = "是".equals(a.getHasProfessionalSkillTest());
                if (hasSkillTest) {
                    return b.getProfessionalSkillTestScore().compareTo(a.getProfessionalSkillTestScore());
                } else {
                    return b.getTotalScore().compareTo(a.getTotalScore());
                }
            });

            // 计算实际可递补人数
            int actualCount = Math.min(required, group.size());
            if (actualCount == 0) continue;

            // 处理同分考生
            boolean hasSkillTest = "是".equals(group.get(0).getHasProfessionalSkillTest());
            BigDecimal baseScore = hasSkillTest ?
                    group.get(actualCount-1).getProfessionalSkillTestScore() :
                    group.get(actualCount-1).getTotalScore();

            for (int i = actualCount; i < group.size(); i++) {
                BigDecimal current = hasSkillTest ?
                        group.get(i).getProfessionalSkillTestScore() :
                        group.get(i).getTotalScore();

                if (current.compareTo(baseScore) == 0) {
                    actualCount++;
                } else {
                    break;
                }
            }

            // 添加最终递补名单
            finalCandidates.addAll(group.subList(0, Math.min(actualCount, group.size())));
        }


        // 修改后的插入逻辑（仅使用身份证号判断）
       /* List<DbIdentityManagement> toInsertList = finalCandidates.stream()
                .filter(score -> StringUtils.isNotEmpty(score.getIdCard())) // 增加身份证号非空校验
                .map(score -> {
                    DbIdentityManagement dbIdentity = new DbIdentityManagement();
                    // 保持原有字段赋值逻辑
                    dbIdentity.setCandidateId(score.getCandidateId());
                    dbIdentity.setName(score.getName());
                    dbIdentity.setGender(score.getGender());
                    dbIdentity.setIdCard(score.getIdCard());
                    dbIdentity.setExamNumber(score.getExamNumber());
                    dbIdentity.setAdministrativeAptitudeScore(score.getAdministrativeAptitudeScore());
                    dbIdentity.setEssayScore(score.getEssayScore());
                    dbIdentity.setProfessionalSubjectScore(score.getProfessionalSubjectScore());
                    dbIdentity.setTotalScore(score.getTotalScore());
                    dbIdentity.setProfessionalSkillTestScore(score.getProfessionalSkillTestScore());
                    dbIdentity.setAppliedUnit(score.getAppliedUnit());
                    dbIdentity.setAppliedPosition(score.getAppliedPosition());
                    dbIdentity.setRecruitmentNumber(score.getRecruitmentNumber());
                    dbIdentity.setInterviewRatio(score.getInterviewRatio());
                    dbIdentity.setRanking(score.getRanking());
                    dbIdentity.setGraduationSchool(score.getGraduationSchool());
                    dbIdentity.setHasProfessionalSkillTest(score.getHasProfessionalSkillTest());
                    dbIdentity.setPositionCategory(score.getPositionCategory());
                    dbIdentity.setIsAlternate(score.getIsAlternate());
                    dbIdentity.setQualificationReviewResult(score.getQualificationReviewResult());
//                            dbIdentity.setIdentityVerificationResult("待验证");  // 默认为待验证
//                            dbIdentity.setPhysicalTestResult(score.getPhysicalTestResult());
//                            dbIdentity.setFinalResult("待确认");  // 默认为待确认
                    dbIdentity.setCreateBy(operName);
                    return dbIdentity;
                }).collect(Collectors.toList());*/


        List<DbQualificationManagement> toInsertList = finalCandidates.stream()
                .filter(score -> StringUtils.isNotEmpty(score.getIdCard())) // 增加身份证号非空校验
                .map(score -> {
                    DbQualificationManagement dbIdentity = new DbQualificationManagement();
                    // 保持原有字段赋值逻辑
                    dbIdentity.setCandidateId(score.getCandidateId());
                    dbIdentity.setName(score.getName());
                    dbIdentity.setGender(score.getGender());
                    dbIdentity.setIdCard(score.getIdCard());
                    dbIdentity.setExamNumber(score.getExamNumber());
                    dbIdentity.setAdministrativeAptitudeScore(score.getAdministrativeAptitudeScore());
                    dbIdentity.setEssayScore(score.getEssayScore());
                    dbIdentity.setProfessionalSubjectScore(score.getProfessionalSubjectScore());
                    dbIdentity.setTotalScore(score.getTotalScore());
                    dbIdentity.setProfessionalSkillTestScore(score.getProfessionalSkillTestScore());
                    dbIdentity.setAppliedUnit(score.getAppliedUnit());
                    dbIdentity.setAppliedPosition(score.getAppliedPosition());
                    dbIdentity.setRecruitmentNumber(score.getRecruitmentNumber());
                    dbIdentity.setInterviewRatio(score.getInterviewRatio());
                    dbIdentity.setRanking(score.getRanking());
                    dbIdentity.setGraduationSchool(score.getGraduationSchool());
                    dbIdentity.setHasProfessionalSkillTest(score.getHasProfessionalSkillTest());
                    dbIdentity.setPositionCategory(score.getPositionCategory());
                    dbIdentity.setIsAlternate(score.getIsAlternate());
                    dbIdentity.setQualificationReviewResult(score.getQualificationReviewResult());
//                            dbIdentity.setIdentityVerificationResult("待验证");  // 默认为待验证
//                            dbIdentity.setPhysicalTestResult(score.getPhysicalTestResult());
//                            dbIdentity.setFinalResult("待确认");  // 默认为待确认
                    dbIdentity.setCreateBy(operName);
                    return dbIdentity;
                }).collect(Collectors.toList());

// 查询已存在的身份证号记录
        /*Set<String> existingIdCards = dbIdentityManagementMapper.selectExistingIdCards(
                toInsertList.stream()
                        .map(DbIdentityManagement::getIdCard)
                        .filter(StringUtils::isNotEmpty)
                        .collect(Collectors.toList())
        );*/

        Set<String> existingIdCards = dbQualificationManagementMapper.selectExistingIdCards(
                toInsertList.stream()
                        .map(DbQualificationManagement::getIdCard)
                        .filter(StringUtils::isNotEmpty)
                        .collect(Collectors.toList())
        );

// 过滤需要插入的数据
        /*List<DbIdentityManagement> filteredList = toInsertList.stream()
                .filter(item -> !existingIdCards.contains(item.getIdCard()))
                .collect(Collectors.toList());*/

        List<DbQualificationManagement> filteredList = toInsertList.stream()
                .filter(item -> !existingIdCards.contains(item.getIdCard()))
                .collect(Collectors.toList());

        if (!filteredList.isEmpty()) {
//            return dbIdentityManagementMapper.batchInsertDbIdentity(filteredList);
            return dbQualificationManagementMapper.batchInsertDbQualification(filteredList);

        }
        return 0;
    }


    /**
     * 获取四级联考身份验证统计数据
     * 
     * @return 统计数据
     */
    @Override
    public StatisticsDTO getIdentityStatistics()
    {
        // 创建返回对象
        StatisticsDTO statisticsDTO = new StatisticsDTO();
        
        // 查询所有身份验证数据
        List<IdentityManagement> identityList = identityManagementMapper.selectIdentityManagementList(new IdentityManagement());
        
        // 总数
        int total = identityList.size();
        statisticsDTO.setTotal(total);
        
        // 通过和未通过数量
        int passed = 0;
        // 职位分布统计
        Map<String, Integer> positionMap = new HashMap<>();
        
        for (IdentityManagement identity : identityList)
        {
            // 统计通过人数
            if ("通过".equals(identity.getIdentityVerificationResult()))
            {
                passed++;
            }
            
            // 统计职位分布
            String position = identity.getAppliedPosition();
            if (position != null && !position.isEmpty())
            {
                positionMap.put(position, positionMap.getOrDefault(position, 0) + 1);
            }
        }
        
        statisticsDTO.setPassed(passed);
        statisticsDTO.setFailed(total - passed);
        
        // 转换职位分布数据为前端所需格式
        List<PositionData> positionDataList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : positionMap.entrySet())
        {
            positionDataList.add(new PositionData(entry.getKey(), entry.getValue()));
        }
        statisticsDTO.setPositionData(positionDataList);
        
        return statisticsDTO;
    }
}
